<?php

namespace common\logics\trade;

use Yii;
use common\models\trade\Trade;
use yii\helpers\Inflector;
use yii\helpers\ArrayHelper;
use common\logics\trade\broadcast\ShopBroadcast;
use common\logics\trade\broadcast\ShopRefundBroadcast;

/**
 * 交易成功后异步通知业务处理
 *
 * @author emhome <emhome@163.com>
 * @since 2.0
 */
class BusinessNotify extends BasePaymentModel {

    use BusinessNotifyTrait;

    /**
     * @var integer  
     */
    public $id;

    /**
     * @var Trade|null 交易模型  
     */
    private $_trade = null;

    /**
     * Creates a form model given a token.
     * @param string $id
     * @param array $config name-value pairs that will be used to initialize the object properties
     * @throws \yii\base\InvalidParamException if token is empty or not valid
     */
    public function __construct($id = null, $config = []) {
        parent::__construct($config);
        if ($id !== null) {
            $this->_trade = Trade::findOne($id);
        }
    }

    /**
     * 获取交易信息
     * @return \common\models\trade\Trade|null
     */
    protected function getTrade() {
        return $this->_trade;
    }

    /**
     * 交易保存
     */
    public function getScopeModel($name) {
        return ArrayHelper::getValue([
            'shop' => ShopBroadcast::class,
            'shop_refund' => ShopRefundBroadcast::class,
        ], $name);
    }

    /**
     * 交易保存
     */
    public function save(&$msg) {
        $trade = $this->getTrade();
        if ($trade == null) {
            $msg = '未查询到交易信息';
            return false;
        }
        if ($trade->status !== Trade::STATUS_SUCCESS) {
            $msg = '未成功交易。当前交易状态为：【' . $trade->status . '】';
            return false;
        }
        $partner = $trade->partner;
        if (!$partner) {
            $msg = '无效通知，无合作商户信息...';
            return false;
        }
        $modelClass = $this->getScopeModel($partner->name);
        if ($modelClass !== null) {
            $model = new $modelClass;
            $model->setAttributes([
                'trade' => $trade,
            ]);
            $status = $model->notify();
            if ($status !== true) {
                $msg = $model->getErrorMsg();
            }
            Yii::error([
                $partner->attributes,
                $modelClass,
                $status,
                $msg,
            ], __METHOD__);
            return $status;
        }
        $method = Inflector::variablize('notify_to_' . $partner->name);
        if (!$this->hasMethod($method)) {
            $msg = '无需通知没有通知路径';
            return true;
        }
        $status = $this->{$method}($msg);
        Yii::error([
            $partner->attributes,
            $method,
            $status,
            $msg,
        ], __METHOD__);
        return $status;
    }

}
